const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const fetch = require('node-fetch');
const path = require('path');
const fs = require('fs');

/**
 * 独立的全局管理服务器
 * 在单独进程中运行，管理所有VSCode窗口的服务器
 */
class GlobalManager {
    constructor() {
        this.server = null;
        this.port = 3700; // 固定端口
        this.registeredServers = new Map(); // 注册的项目服务器
        this.healthCheckInterval = null;
        
        // 项目服务器信息存储文件
        this.dataFile = path.join(require('os').tmpdir(), 'vscode-web-login-plugin-servers.json');
        
        this.loadServersFromFile();
        this.startHealthCheck();
    }

    /**
     * 从文件加载服务器信息
     */
    loadServersFromFile() {
        try {
            if (fs.existsSync(this.dataFile)) {
                const data = fs.readFileSync(this.dataFile, 'utf8');
                const servers = JSON.parse(data);
                
                // 恢复Map结构
                this.registeredServers = new Map(servers.map(item => [
                    item.projectPath,
                    {
                        port: item.port,
                        projectName: item.projectName,
                        windowId: item.windowId,
                        lastHeartbeat: item.lastHeartbeat || Date.now(),
                        frontendPort: this.getProjectFrontendPort(item.projectPath)
                    }
                ]));
                
                console.log(`从文件加载了 ${this.registeredServers.size} 个服务器信息`);
            }
        } catch (error) {
            console.error('加载服务器信息失败:', error);
            this.registeredServers = new Map();
        }
    }

    /**
     * 保存服务器信息到文件
     */
    saveServersToFile() {
        try {
            const servers = Array.from(this.registeredServers.entries()).map(([projectPath, info]) => ({
                projectPath,
                port: info.port,
                projectName: info.projectName,
                windowId: info.windowId,
                lastHeartbeat: info.lastHeartbeat,
                frontendPort: info.frontendPort
            }));
            
            fs.writeFileSync(this.dataFile, JSON.stringify(servers, null, 2));
        } catch (error) {
            console.error('保存服务器信息失败:', error);
        }
    }

    /**
     * 获取项目前端端口
     */
    getProjectFrontendPort(projectPath) {
        try {
            const configPath = path.join(projectPath, 'packages/server/conf/configuration.json');
            if (!fs.existsSync(configPath)) {
                return 3000;
            }
            
            const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
            return config.PORT || 3000;
        } catch (error) {
            return 3000;
        }
    }

    /**
     * 启动健康检查
     */
    startHealthCheck() {
        // 每30秒检查一次服务器健康状态
        this.healthCheckInterval = setInterval(async () => {
            await this.checkServersHealth();
        }, 30000);
    }

    /**
     * 检查服务器健康状态
     */
    async checkServersHealth() {
        const now = Date.now();
        const timeout = 60000; // 60秒超时
        
        for (const [projectPath, info] of this.registeredServers.entries()) {
            // 如果超过60秒没有心跳，认为服务器已断开
            if (now - info.lastHeartbeat > timeout) {
                console.log(`服务器 ${projectPath} 心跳超时，移除注册信息`);
                this.registeredServers.delete(projectPath);
                this.saveServersToFile();
                continue;
            }

            // 尝试ping服务器
            try {
                const response = await fetch(`http://localhost:${info.port}/api/health`, {
                    timeout: 3000
                });
                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}`);
                }
            } catch (error) {
                console.log(`服务器 ${projectPath} 健康检查失败: ${error.message}`);
                // 可以选择是否立即移除，这里保守一点，只记录错误
            }
        }
    }

    /**
     * 启动全局管理服务器
     */
    async start() {
        if (this.server) {
            console.log('全局管理服务器已在运行');
            return this.port;
        }

        const app = new Koa();
        const router = new Router();

        app.use(bodyParser());

        // CORS中间件
        app.use(async (ctx, next) => {
            ctx.set('Access-Control-Allow-Origin', '*');
            ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
            ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
            
            if (ctx.method === 'OPTIONS') {
                ctx.status = 200;
                return;
            }
            await next();
        });

        // 注册服务器接口
        router.post('/api/global/register', async (ctx) => {
            const { projectPath, port, windowId } = ctx.request.body;
            
            if (!projectPath || !port) {
                ctx.status = 400;
                ctx.body = { error: '缺少必要参数' };
                return;
            }

            const projectName = path.basename(projectPath);
            const frontendPort = this.getProjectFrontendPort(projectPath);
            
            this.registeredServers.set(projectPath, {
                port,
                projectName,
                windowId: windowId || 'unknown',
                lastHeartbeat: Date.now(),
                frontendPort
            });

            this.saveServersToFile();
            
            console.log(`注册服务器: ${projectName} (${projectPath}) -> 端口 ${port}`);
            
            ctx.body = {
                success: true,
                message: '服务器注册成功',
                data: { projectPath, port, frontendPort }
            };
        });

        // 注销服务器接口
        router.post('/api/global/unregister', async (ctx) => {
            const { projectPath } = ctx.request.body;
            
            if (this.registeredServers.has(projectPath)) {
                this.registeredServers.delete(projectPath);
                this.saveServersToFile();
                console.log(`注销服务器: ${projectPath}`);
                ctx.body = { success: true, message: '服务器注销成功' };
            } else {
                ctx.status = 404;
                ctx.body = { error: '服务器未找到' };
            }
        });

        // 心跳接口
        router.post('/api/global/heartbeat', async (ctx) => {
            const { projectPath } = ctx.request.body;
            
            if (this.registeredServers.has(projectPath)) {
                this.registeredServers.get(projectPath).lastHeartbeat = Date.now();
                ctx.body = { success: true };
            } else {
                ctx.status = 404;
                ctx.body = { error: '服务器未注册' };
            }
        });

        // 获取所有项目列表
        router.get('/api/global/projects', async (ctx) => {
            const projects = Array.from(this.registeredServers.entries()).map(([projectPath, info]) => ({
                projectPath,
                projectName: info.projectName,
                port: info.port,
                frontendPort: info.frontendPort,
                windowId: info.windowId,
                apiUrl: `http://localhost:${info.port}`,
                frontendUrl: `http://localhost:${info.frontendPort}`,
                status: Date.now() - info.lastHeartbeat < 60000 ? 'online' : 'offline',
                lastHeartbeat: new Date(info.lastHeartbeat).toISOString()
            }));

            ctx.body = {
                success: true,
                data: projects,
                total: projects.length
            };
        });

        // 健康检查接口
        router.get('/api/global/health', async (ctx) => {
            ctx.body = {
                status: 'ok',
                message: '全局管理服务器运行正常',
                port: this.port,
                serverCount: this.registeredServers.size,
                timestamp: new Date().toISOString()
            };
        });

        // 获取所有账号列表接口 - 通过代理转发到第一个可用的项目服务器
        router.get('/api/global/getAllAccounts', async (ctx) => {
            try {
                // 找到第一个在线的项目服务器
                let targetServer = null;
                const now = Date.now();
                
                for (const [projectPath, info] of this.registeredServers.entries()) {
                    // 检查服务器是否在线（60秒内有心跳）
                    if (now - info.lastHeartbeat < 60000) {
                        targetServer = info;
                        break;
                    }
                }

                if (!targetServer) {
                    ctx.status = 503;
                    ctx.body = {
                        success: false,
                        error: '没有可用的项目服务器',
                        message: '请确保至少有一个VSCode窗口已打开并加载了扩展'
                    };
                    return;
                }

                // 代理请求到目标服务器
                const targetUrl = `http://localhost:${targetServer.port}/api/getAllAccounts`;
                
                const response = await fetch(targetUrl, {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    timeout: 10000
                });

                ctx.status = response.status;
                
                if (response.ok) {
                    const data = await response.json();
                    ctx.body = data;
                } else {
                    const errorText = await response.text();
                    ctx.body = {
                        success: false,
                        error: '获取账号列表失败',
                        message: errorText,
                        targetServer: targetServer.projectName
                    };
                }
                
            } catch (error) {
                console.error('获取账号列表失败:', error);
                ctx.status = 500;
                ctx.body = {
                    success: false,
                    error: '获取账号列表失败',
                    message: error.message
                };
            }
        });

        // 代理接口：根据前端端口路由到对应项目
        router.all('/api/:frontendPort/(.*)', async (ctx) => {
            const frontendPort = parseInt(ctx.params.frontendPort);
            const remainingPath = ctx.params[0];
            
            // 找到对应的项目服务器
            let targetServer = null;
            for (const [projectPath, info] of this.registeredServers.entries()) {
                if (info.frontendPort === frontendPort) {
                    targetServer = info;
                    break;
                }
            }

            if (!targetServer) {
                ctx.status = 404;
                ctx.body = { 
                    error: '项目未找到',
                    message: `前端端口 ${frontendPort} 对应的项目未注册`,
                    availableProjects: Array.from(this.registeredServers.values()).map(info => ({
                        projectName: info.projectName,
                        frontendPort: info.frontendPort,
                        port: info.port
                    }))
                };
                return;
            }

            // 代理请求
            try {
                const targetUrl = `http://localhost:${targetServer.port}/api/${remainingPath}`;
                
                const requestOptions = {
                    method: ctx.method,
                    headers: { ...ctx.headers, host: `localhost:${targetServer.port}` },
                    timeout: 10000
                };

                if (ctx.request.body && ['POST', 'PUT', 'PATCH'].includes(ctx.method.toUpperCase())) {
                    requestOptions.body = JSON.stringify(ctx.request.body);
                    requestOptions.headers['content-type'] = 'application/json';
                }

                const response = await fetch(targetUrl, requestOptions);
                ctx.status = response.status;
                
                const contentType = response.headers.get('content-type') || '';
                if (contentType.includes('application/json')) {
                    ctx.body = await response.json();
                } else {
                    ctx.body = await response.text();
                }
                
            } catch (error) {
                ctx.status = 500;
                ctx.body = { 
                    error: '代理请求失败', 
                    message: error.message,
                    targetPort: targetServer.port
                };
            }
        });

        app.use(router.routes());
        app.use(router.allowedMethods());

        return new Promise((resolve, reject) => {
            this.server = app.listen(this.port, 'localhost', () => {
                console.log(`全局管理服务器已启动，端口: ${this.port}`);
                console.log(`管理界面: http://localhost:${this.port}/api/global/projects`);
                resolve(this.port);
            });

            this.server.on('error', (err) => {
                if (err.code === 'EADDRINUSE') {
                    this.port++;
                    this.start().then(resolve).catch(reject);
                } else {
                    reject(err);
                }
            });
        });
    }

    /**
     * 停止服务器
     */
    stop() {
        if (this.server) {
            this.server.close();
            this.server = null;
        }
        
        if (this.healthCheckInterval) {
            clearInterval(this.healthCheckInterval);
            this.healthCheckInterval = null;
        }
        
        console.log('全局管理服务器已停止');
    }

    /**
     * 获取端口
     */
    getPort() {
        return this.port;
    }
}

// 如果直接运行此文件，启动全局管理服务器
if (require.main === module) {
    const manager = new GlobalManager();
    manager.start().then((port) => {
        console.log(`全局管理服务器已启动在端口 ${port}`);
        console.log('按 Ctrl+C 停止服务器');
    }).catch(console.error);

    // 优雅退出
    process.on('SIGINT', () => {
        console.log('\n正在停止全局管理服务器...');
        manager.stop();
        process.exit(0);
    });
}

module.exports = GlobalManager; 